package cn.flashapp.queue.threadpool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolManager {
	private ExecutorService service = null;
	private static ThreadPoolManager manager = null;

	public static ThreadPoolManager getInstance(int min, int maxNum,
			int activeTime, int queueSize) {
		if (manager == null) {
			manager = new ThreadPoolManager(min, maxNum, activeTime, queueSize);
		}
		return manager;
	}

	private ThreadPoolManager(int min, int maxNum, int activeTime, int queueSize) {
		service = new ThreadPoolExecutor(min, maxNum, activeTime,
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize),
				new ThreadPoolExecutor.CallerRunsPolicy());
	}

	/**
	 * 执行线程任务,返回结果. 如果线程池数量全部占用,则此线程阻塞. 线程运行的传入参数类的实现方法.
	 * 
	 * @param task
	 *            实现java.util.concurrent.Callable接口的类
	 * @return 返回线程运行的结果
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	// @SuppressWarnings("unchecked")
	// public Object runTask(Callable task) throws InterruptedException,
	// ExecutionException {
	// if (maxNum > 0)
	// semp.acquire();// 使用信号标记,如果超过个数会造成线程阻塞
	// Future f = service.submit(task);// 加载线程任务,并且执行
	// if (maxNum > 0)
	// semp.release();// 信号释放
	// return f.get();// 返回线程处理的结果,如果此线程尚未处理完成,则线程阻塞直到返回结果
	// }

	/**
	 * 执行线程任务,没有返回结果. 如果线程池数量全部占用,则此线程阻塞. 线程运行的传入参数类的实现方法.
	 * 
	 * @param command
	 *            实现jRunnable接口的类
	 * @return void
	 * @throws InterruptedException
	 */
	public void execute(Runnable command) throws InterruptedException {
		// if (maxNum > 0)
		// semp.acquire();// 使用信号标记,如果超过个数会造成线程阻塞
		service.execute(command);
		// if (maxNum > 0)
		// semp.release();// 信号释放
	}

	/**
	 * @return 返回线程可用数量
	 */
	// public synchronized int getavailableNum() {
	// return this.semp.availablePermits();
	// }

	/**
	 * 关闭线程池
	 */
	public final void close() {
		if (service != null)
			service.shutdown();
		service = null;
	}
}
